package com.ruoyi.aitapp.utils;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.aitapp.vo.BarcodeConfigVO;
import com.ruoyi.aitcommon.config.ConfigManager;
import com.ruoyi.aitcommon.utils.*;
import com.ruoyi.aitcommon.vo.PageDataVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Component
public class BarcodeConfigUtils {
    @Autowired
    APPDataUtils appDataUtils;
    @Autowired
    APPConfigUtils appConfigUtils;
    @Autowired
    U9RestUtils u9RestUtils;
    @Autowired
    ConfigManager configManager;
    public BarcodeConfigVO getConfig() throws Exception {
        JSONObject json = (JSONObject)configManager.getContextByParm("appconfig.BarCodeConfig",false);
        BarcodeConfigVO config = JSONObject.toJavaObject(json, BarcodeConfigVO.class);
        return config;
    }

    /**
     * 下载PDF打印文件,调用本地打印机,打印条码
     * @param config 条码配置
     * @param data 接口数据
     */
    public void printBarcode(BarcodeConfigVO config, JSONObject data) throws Exception {
        ExceptionUtils.checkBlankOrUndefined(config.getPrints(),"条码未配置prints");
        BarcodeConfigVO.Print printVO=null;
        if(ObjUtils.isBlank(data.getString("printTemplateID"))){
            //未传入打印模板,默认使用第一个打印模板
            printVO = config.getPrints().get(0);
        }else{
            for(BarcodeConfigVO.Print printVO1:config.getPrints()) {
                if (printVO1.getPrintTemplateID().equals(data.getString("printTemplateID"))) {
                    printVO = printVO1;
                    break;
                }
            }
        }
        if(printVO==null) ExceptionUtils.throwException(null,"依据模板ID[{}]获取打印信息为空");
        ExceptionUtils.checkBlankOrUndefined(data.getString("username"),"[username]为空");

        //调用U9服务获取打印PDF
        JSONObject params = new JSONObject();
        params.put("PrintCatalog","");
        params.put("PrintTmplID", printVO.getPrintTemplateID());
        params.put("DataView",printVO.getErpView());
        //构造path
        ExceptionUtils.checkBlankOrUndefined(printVO.getErpPath(),"erpPath为空");
        String dataPath = (String) JSONParamUtils.transParamsJSONValue(printVO.getErpPath(), data, false);
        params.put("DataPath",dataPath);
        params.put("SaveDir",printVO.getErpSaveDir());
        final Object ret = u9RestUtils.callU9Rest(params,printVO.getErpUrl(), params);
        //下载pdf文档
        String erpUrl = appConfigUtils.getAPPParamsString("erprest.url");
        erpUrl=StrUtil.removeSuffix(erpUrl,"RestServices");
        final JSONObject u9data = JSONUtils.getJSONObjectByObject(ret);
        final String fileUrl = erpUrl+u9data.getString("url");
        final String fileName = u9data.getString("fileName");
        final String filePath = "fileserver/barcode/print/"+fileName;
        File file=RestServiceUtils.getFile(fileUrl,filePath);
        //打印pdf文档
        PrintUtils.printPDF(file.getAbsolutePath(),printVO.getPrinterName());
    }
    /**
     * 解析条码配置,返回条码结构的值
     *
     * @param config 条码配置
     * @param data   条码值,结构 {"barcode":"","item":""}
     */
    public Map<String,Object> parseBarcodeConfig(BarcodeConfigVO config, JSONObject data) throws Exception {
        ExceptionUtils.checkBlankOrUndefined(data.getString("barcode"), "barcode为空");
//        ExceptionUtils.checkBlankOrUndefined(data.getString("item"), "item为空");
        ExceptionUtils.checkBlankOrUndefined(config, "config为空");

        // 获取规则
        final BarcodeConfigVO.Rule rule = getRule(config, data.getString("item"));
        // 依据规则解析条码
        String barcode = data.getString("barcode");
        final List<String> split = StrUtil.split(barcode, rule.getDelimiter());
        if (split.size() != rule.getLines().size()) {
            throw new Exception("条码长度与规则不匹配");
        }
        // 使用LinkedHashMap, 保证返回顺序
        Map<String,Object> ret = new LinkedHashMap<>();
        ret.put("barcode",barcode);
        for (int i = 0; i < rule.getLines().size(); i++) {
            //循环设置字段值
            final BarcodeConfigVO.Line line = rule.getLines().get(i);
            final String code = line.getCode();
            final String name = line.getName();
            final String value = split.get(i);// 获取条码分段值
            if (line.isRequired() && StrUtil.isBlank(value)){
                throw new Exception("规则[" + code + "]为必填项,值为空");
            }
            if(ObjUtils.isNotBlank(line.getVerify())){
                // 验证规则
                if(line.getVerify().equals("item")){
                    //料品校验
                    final String pItem = data.getString("item");//传入item值
                    if(ObjUtils.isNotBlank(pItem)&&!(value.equals(pItem)))
                        ExceptionUtils.throwException(null,"条码字段[{}]值为[{}],与传入值[{}]不同",name,value,pItem);
                }
            }
            ret.put(code, value);
        }
        for (int i = 0; i < rule.getLines().size(); i++) {
            //基于参照类型,覆盖现有值
            final BarcodeConfigVO.Line line = rule.getLines().get(i);
            final String type = line.getType();
            if(type!=null&&type.equals("ref")){
                //参照类型字段从ERP获取数据
                ExceptionUtils.checkBlankOrUndefined(line.getRefView(),"refView 为空");
                ExceptionUtils.checkBlankOrUndefined(line.getRefPath(),"refPath 为空");
                //类型=ref时,获取ERP相关数据
                final Object path = JSONParamUtils.transParamsJSONValue(line.getRefPath(), ret, false);
                final PageDataVO viewData = appDataUtils.queryERPByParam(line.getRefView(), path.toString(),"", null);
                if(viewData.getRows()!=null&&viewData.getRows().size()>0){
                    ret.putAll(viewData.getRows().get(0));
                }
            }
        }
        return ret;
    }

    /**
     * 依据料号,获取条码规则
     * @param config 条码配置
     * @param item 料号
     * @return
     */
    private BarcodeConfigVO.Rule getRule(BarcodeConfigVO config, String item) throws Exception {
        if(ObjUtils.isBlank(config.getRules()))
            throw new Exception("条码规则为空");

        //获取规则编码
        String ruleCode = null;
        if(ObjUtils.isBlank(item)){
            //料号为空,默认取第一个编码规则
            ruleCode=config.getRules().get(0).getCode();
        }else{
            //料号不为空时,依据料号获取规则编码
            for (BarcodeConfigVO.Assign assign : config.getAssign()) {
                for (String category : assign.getCategory().split(",")) {
                    if (StrUtil.startWith(item, category)) {
                        ruleCode = assign.getRuleCode();
                        break; // 找到匹配的 ruleCode 后跳出内层循环
                    }
                }
                if (ruleCode != null) {
                    break; // 找到匹配的 ruleCode 后跳出外层循环
                }
            }
        }
        ExceptionUtils.checkBlankOrUndefined(ruleCode, "依据料号[{}]匹配编码规则为空",item);

        // 获取规则
        BarcodeConfigVO.Rule rule = null;
        for (BarcodeConfigVO.Rule r : config.getRules()) {
            if (r.getCode().equals(ruleCode)) {
                rule = r;
                break; // 找到匹配的 Rule 后跳出循环
            }
        }
        if (rule == null) {
            throw new Exception("获取规则为空");
        }

        return rule;
    }
}